package java_thinking.unit_14._14_2;

/**
 * @Description : 一个class被装载入内存，它就被用来创建这个类的所有对象
 *              所有类都是在对其第一次使用时动态加载到JVM中的，当程序创建第一个对类的静态成员的应用时，就会加载这个类，
 *              这证明构造器也是类的静态方法即使在构造器之前并没有使用static关键字，因此，使用new操作符创建类的新对象
 *              也会被当做对类的静态成员的引用
 *
 *              .class来创建Class对象的应用时，不会自动的初始化该Class对象，为了使用类而做的准备工作实际包含三个步骤：
 *                  1.加载：这是由类加载器执行的，该步骤将查找字节码，并从这些字节码中创建一个Class对象
 *                  2.链接：在链接阶段将验证类中的字节码，为静态域分配存储空间，并且如果必须的话将解析这个类的创建的对其他类的所有引用
 *                  3.初始化：如果该类具有超类，则对其进行初始化，执行静态初始化器和静态初始化块
 *              初始化被延迟到了对静态方法或者非静态域进行首次引用时才执行，为了产生Class引用，Class.forName()立即就进行了初始化
 *              如果一个static final值 是编译期常量，那这个值就不需要对类进行初始化就可以被读取，如果只是static或者是final的则需要初始化类
 *              如果一个static域 不是final的。那么在对它访问时总是要先进行链接和初始化(初始化该存储空间)
 * @author: cww
 * @DateTime: 2019/3/26 19:09
 */
class Candy {
    static int i = 9;
    static {
        System.out.println("Loading Candy");
    }
}
class Gum {
    static int e = 8;
    static {
        System.out.println("Loading Gum");
    }
}
class Cookie {
    static int c = 7;
    static {
        System.out.println("Loading Cookie");
    }
}
public class SweetShop {
    public static void main(String[] args) {
        System.out.println("inside Main");
        /**
         * 当程序创建第一个对类的静态成员的应用时，就会加载这个类
         */
        System.out.println(Candy.i);
        System.out.println("After creating Candy");
        try {
            Class.forName("Gum");
        } catch (ClassNotFoundException e) {
            System.out.println("Couldn't find Gum");
        }
        System.out.println("After class.forName(\"Gum\")");
        /**
         * 使用new操作符创建类的新对象
         * 也会被当做对类的静态成员的引用
         */
        Cookie cookie = new Cookie();
        System.out.println(cookie.c);
        System.out.println("After loading Cookie");
    }
}
